/**
 * 扫描连接类
 */

var readServiceUUID = [];
var readCharacteristicUUID = [];
var writeWithResponseServiceUUID = [];
var writeWithResponseCharacteristicUUID = [];
var writeWithoutResponseServiceUUID = [];
var writeWithoutResponseCharacteristicUUID = [];
var nofityServiceUUID = [];
var nofityCharacteristicUUID = [];
import { Platform } from 'react-native';
import BleManager from 'react-native-ble-manager';
import { deviceStore } from '~/store';
import { applyBloodDevice, } from '~/utils/deviceMenues';

//sdk13的空中升级
var sdk_13_characteristicUUID = '8EC90003-F315-4F60-9FB8-838830DAEA50';
var sdk_13_servicesUUID = 'FE59';

export default class BleConnection {
    static getInstance() {
        if (!BleConnection.instance) {
            BleConnection.instance = new BleConnection();
        }
        return BleConnection.instance;
    }
    constructor() {
        this.isConnecting = false; //蓝牙是否连接
        this.initUUID();
        this.peripheralId = null;
    }
    /**
     * 扫描可用设备，5秒后结束
     * Scan for availables peripherals.
     * */
    scan(s = 5) {
        return new Promise((resolve, reject) => {
            BleManager.scan([], s, true)
                .then(() => {
                    console.log('开始搜索蓝牙设备');
                    resolve();
                })
                .catch((err) => {
                    console.log('搜索蓝牙失败', err);
                    reject(err);
                });
        });
    }

    scanResult() {
        return new Promise((resolve, reject) => {
            BleManager.getDiscoveredPeripherals()
                .then((res) => {
                    resolve(res);
                })
                .catch((err) => {
                    reject(err);
                });
        });
    }

    /**
     * 停止扫描
     * Stop the scanning.
     * */
    stopScan() {
        return new Promise((resolve, reject) => {
            BleManager.stopScan()
                .then(() => {
                    console.log('Scan stopped');
                    resolve();
                })
                .catch((err) => {
                    reject(err);
                });
        });
    }
    /**
     * 打开蓝牙(Android only)
     * Create the request to the user to activate the bluetooth
     * */
    enableBluetooth() {
        return new Promise((resolve, reject) => {
            BleManager.enableBluetooth()
                .then(() => {
                    resolve();
                    // console.log('The bluetooh is already enabled or the user confirm');
                })
                .catch((error) => {
                    reject(error);
                    // console.log('The user refuse to enable bluetooth');
                });
        });
    }
    /**
     * Converts UUID to full 128bit.
     *
     * @param {UUID} uuid 16bit, 32bit or 128bit UUID.
     * @returns {UUID} 128bit UUID.
     */
    fullUUID(uuid) {
        if (uuid.length === 4) {
            return '0000' + uuid.toUpperCase() + '-0000-1000-8000-00805F9B34FB';
        }
        if (uuid.length === 8) {
            return uuid.toUpperCase() + '-0000-1000-8000-00805F9B34FB';
        }
        return uuid.toUpperCase();
    }
    initUUID() {
        this.readServiceUUID = [];
        this.readCharacteristicUUID = [];
        this.writeWithResponseServiceUUID = [];
        this.writeWithResponseCharacteristicUUID = [];
        this.writeWithoutResponseServiceUUID = [];
        this.writeWithoutResponseCharacteristicUUID = [];
        this.nofityServiceUUID = [];
        this.nofityCharacteristicUUID = [];
    }

    //获取Notify、Read、Write、WriteWithoutResponse的serviceUUID和characteristicUUID
    getUUID(peripheralInfo) {
        this.readServiceUUID = [];
        this.readCharacteristicUUID = [];
        this.writeWithResponseServiceUUID = [];
        this.writeWithResponseCharacteristicUUID = [];
        this.writeWithoutResponseServiceUUID = [];
        this.writeWithoutResponseCharacteristicUUID = [];
        this.nofityServiceUUID = [];
        this.nofityCharacteristicUUID = [];
        for (let item of peripheralInfo.characteristics) {
            item.service = this.fullUUID(item.service);
            item.characteristic = this.fullUUID(item.characteristic);
            if (Platform.OS == 'android') {
                if (item.properties.Notify == 'Notify') {
                    this.nofityServiceUUID.push(item.service);
                    this.nofityCharacteristicUUID.push(item.characteristic);
                }
                if (item.properties.Read == 'Read') {
                    this.readServiceUUID.push(item.service);
                    this.readCharacteristicUUID.push(item.characteristic);
                }
                if (item.properties.Write == 'Write') {
                    this.writeWithResponseServiceUUID.push(item.service);
                    this.writeWithResponseCharacteristicUUID.push(item.characteristic);
                }
                if (item.properties.WriteWithoutResponse == 'WriteWithoutResponse') {
                    this.writeWithoutResponseServiceUUID.push(item.service);
                    this.writeWithoutResponseCharacteristicUUID.push(item.characteristic);
                }
            } else {
                //ios
                for (let property of item.properties) {
                    if (property == 'Notify') {
                        this.nofityServiceUUID.push(item.service);
                        this.nofityCharacteristicUUID.push(item.characteristic);
                    }
                    if (property == 'Read') {
                        this.readServiceUUID.push(item.service);
                        this.readCharacteristicUUID.push(item.characteristic);
                    }
                    if (property == 'Write') {
                        this.writeWithResponseServiceUUID.push(item.service);
                        this.writeWithResponseCharacteristicUUID.push(item.characteristic);
                    }
                    if (property == 'WriteWithoutResponse') {
                        this.writeWithoutResponseServiceUUID.push(item.service);
                        this.writeWithoutResponseCharacteristicUUID.push(item.characteristic);
                    }
                }
            }
        }
        console.log('readServiceUUID', this.readServiceUUID);
        console.log('readCharacteristicUUID', this.readCharacteristicUUID);
        console.log('writeWithResponseServiceUUID', this.writeWithResponseServiceUUID);
        console.log('writeWithResponseCharacteristicUUID', this.writeWithResponseCharacteristicUUID);
        console.log('writeWithoutResponseServiceUUID', this.writeWithoutResponseServiceUUID);
        console.log('writeWithoutResponseCharacteristicUUID', this.writeWithoutResponseCharacteristicUUID);
        console.log('nofityServiceUUID', this.nofityServiceUUID);
        console.log('nofityCharacteristicUUID', this.nofityCharacteristicUUID);
    }

    //定时器

    timeOut(time) {
        return new Promise(function (resolve) {
            setTimeout(function () {
                resolve();
            }, time);
        });
    }

    async retrieveServices(id) {
        var info = null;
        try {
            info = await BleManager.retrieveServices(id);
            if (info) {
                // console.log(info, '获取的retrieveServicesretrieveServices')
                return info;
            } else {
                this.retrieveServices(id);
            }
        } catch (error) {
            this.retrieveServices(id);
        }
    }

    /**
     * 连接蓝牙
     * Attempts to connect to a peripheral.
     * */
    connect(id) {
        this.isConnecting = true;
        return new Promise(async (resolve, reject) => {
            try {
                await BleManager.connect(id);
                BleManager.stopScan();

                const peripheralInfo = await this.retryRetrieveServices(id, 2); // ✅ 封装重试

                this.peripheralId = peripheralInfo.id;
                this.getUUID(peripheralInfo);
                this.isConnecting = false;

                resolve(peripheralInfo);

                // ✅ 后续异步处理
                setTimeout(() => {
                    if (applyBloodDevice.includes(peripheralInfo?.advertising?.localName)) {
                        this.startNotifi(1);
                    }
                }, 0);
            } catch (error) {
                console.log('Connected error:', error);
                BleManager.stopScan();
                this.isConnecting = false;
                reject(error);
            }
        });
    }

    async retryRetrieveServices(id, maxRetries = 2) {
        for (let i = 0; i < maxRetries; i++) {
            try {
                const info = await BleManager.retrieveServices(id);
                if (info?.characteristics?.length > 0) return info;
            } catch (e) {
                console.warn(`retrieveServices 第 ${i + 1} 次失败`);
            }
            await this.timeOut(200);
        }
        throw new Error('无法获取设备 characteristics');
    }
    /**
     * 断开蓝牙连接
     * Disconnect from a peripheral.
     * */
    disconnect() {
        console.log(this.peripheralId, '断开id');
        this.stopNotification()
        return new Promise((resolve, reject) => {
            BleManager.disconnect(this.peripheralId)
                .then(() => {
                    this.isConnecting = false;
                    console.log('Disconnected');
                    this.initUUID(); //断开连接后清空UUID
                    resolve();
                })
                .catch((error) => {
                    console.log('Disconnected error:', error);
                    reject(error);
                });
        });
    }

    async startNotification_china(index = 1) {
        try {
            console.log(this.nofityServiceUUID[index], this.nofityCharacteristicUUID[index], '通知的信息');
            const result = await BleManager.startNotification(
                this.peripheralId,
                '02F00000-0000-0000-0000-00000000FE00',
                '02F00000-0000-0000-0000-00000000FF02',
            );
            console.log(result, '通知成功');
            return result;
        } catch (error) {
            console.log(error, '通知');
            return error;
        }
    }

    /**
     * 国产蓝牙芯片空中升级指令发送
     * 参数：(peripheralId, serviceUUID, characteristicUUID, data, maxByteSize)
     * Write with response to the specified characteristic, you need to call retrieveServices method before.
     * */
    async write_china(data) {
        try {
            // console.log(this.peripheralId, this.writeWithResponseServiceUUID[index], this.writeWithResponseCharacteristicUUID[index], "请求的uuid")

            // const result = await BleManager.write(this.peripheralId, "9C2C4841-69C3-4742-9F69-764351FB0783", "9C2C48A5-69C3-4742-9F69-764351FB0783", data);
            const result = await BleManager.write(
                this.peripheralId,
                '02F00000-0000-0000-0000-00000000FE00',
                '02F00000-0000-0000-0000-00000000FF01',
                data,
                data.length,
            );
            console.log(result, '写入数据的结果');
            return result;
        } catch (error) {
            console.log(error, '写入失败2132');
            return error;
        }
        // data = this.addProtocol(data);   //在数据的头尾加入协议格式，如0A => FEFD010AFCFB，不同的蓝牙协议应作相应的更改
    }

    async requesMtu(size) {
        try {
            const mtu = await BleManager.requestMTU(this.peripheralId, size);
            console.log('MTU size changed to ' + mtu + ' bytes');
            return mtu;
        } catch (e) {
            return size;
        }
    }

    /**
     * 打开通知
     * Start the notification on the specified characteristic.
     * */
    async startNotification(index = 0) {
        try {
            if (!this.peripheralId || !this.nofityServiceUUID[index] || !this.nofityCharacteristicUUID[index]) {
                throw new Error('通知 UUID 无效');
            }

            const result = await BleManager.startNotification(
                this.peripheralId,
                this.nofityServiceUUID[index],
                this.nofityCharacteristicUUID[index]
            );

            console.log('打开通知成功', result);
            return result;
        } catch (error) {
            // console.error('打开通知 error', error);
            return error;
        }
    }

    //sdk13打开通知
    startNotification_sdk13(index = 0) {
        return new Promise((resolve, reject) => {
            BleManager.startNotification(this.peripheralId, sdk_13_servicesUUID, sdk_13_characteristicUUID)
                .then(() => {
                    console.log('Notification started');
                    resolve();
                })
                .catch((error) => {
                    console.log('Notification error:', error);
                    reject(error);
                });
        });
    }

    /**
     * 关闭通知
     * Stop the notification on the specified characteristic.
     * */
    async stopNotification(index = 0) {
        try {
            if (!this.peripheralId || !this.nofityServiceUUID[index] || !this.nofityCharacteristicUUID[index]) {
                throw new Error('stopNotification 参数无效');
            }
            await BleManager.stopNotification(
                this.peripheralId,
                this.nofityServiceUUID[index],
                this.nofityCharacteristicUUID[index]
            );
            // console.log('stopNotification success!');
        } catch (error) {
            // console.error('stopNotification error:', error);
            throw error;
        }
    }
    /* 打开通知开关 */
    async startNotifi(index) {
        try {
            BleManager.startNotification(
                this.peripheralId,
                this.nofityServiceUUID[0],
                this.nofityCharacteristicUUID[index],
            ).then((res) => {
                console.log('打开通知成功', res);
            });
        } catch (error) {
            console.log('打开通知errerrorerrorerror', error);
        }
    }
}
